package tech.waterism.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 常用函数
 *
 * @author Administrator
 */
public class CommonFun {

    public static Date datePlusHour(Date date, int hour) { // 在指定的时间加上指定的小时数所得的时间
        if (date == null)
            return null;
        Calendar time = Calendar.getInstance();
        time.setTime(date);
        // 夏令时
        int dstOffset0 = time.get(Calendar.DST_OFFSET);
        time.add(Calendar.HOUR_OF_DAY, hour);
        // 夏令时
        int dstOffset1 = time.get(Calendar.DST_OFFSET);
        time.add(Calendar.MILLISECOND, -(dstOffset1 - dstOffset0));

        return time.getTime();
    }

    public static Date datePlusDays(Date date, int day) { // 在指定的时间加上指定的天数数所得的时间
        if (date == null)
            return null;
        Calendar time = Calendar.getInstance();
        time.setTime(date);
        time.add(Calendar.DATE, day);

        return time.getTime();
    }

    // 包括开始时间
    public static int getPeriods(Date dt_beg, Date dt_end, int time_step, String step_unit) {
        int periods = -1;
        if ((dt_end.getTime() - dt_beg.getTime()) >= 0) {
            switch (step_unit) {
                case "D":
                    return new Long((dt_end.getTime() - dt_beg.getTime()) / (time_step * 24 * 3600 * 1000L))
                            .intValue() + 1;
                case "H":
                    return new Long((dt_end.getTime() - dt_beg.getTime()) / (time_step * 3600 * 1000L)).intValue() + 1;
                case "M":
                    return new Long((dt_end.getTime() - dt_beg.getTime()) / (time_step * 60 * 1000L)).intValue() + 1;
                default:
                    return new Long((dt_end.getTime() - dt_beg.getTime()) / (time_step * 3600 * 1000L)).intValue() + 1;
            }
        }
        return periods;
    }

    public static int getMinutes(Date dt_beg, Date dt_end) {
        int minutes = -1;
        minutes = new Long((dt_end.getTime() - dt_beg.getTime()) / (60 * 1000L)).intValue();
        return minutes;
    }

    public static int getHours(Date dt_beg, Date dt_end) {
        int hours = -1;
        hours = new Long((dt_end.getTime() - dt_beg.getTime()) / (3600 * 1000L)).intValue();
        return hours;
    }

    public static double getDays(Date dt_beg, Date dt_end, int time_step, String step_unit) {
//        return (double) DateUtil.between(dt_beg, dt_end, DateUnit.DAY, false);
        return (dt_end.getTime() - dt_beg.getTime()) / (24 * 3600.0 * 1000L);
    }

    public static String getFloodNoFromDt(Date dt) {
        String floodNo;
        String pattern = "00";
        DecimalFormat df = new DecimalFormat(pattern);

        Calendar time = Calendar.getInstance();
        time.setTime(dt);
        int year = time.get(Calendar.YEAR);
        int month = time.get(Calendar.MONTH) + 1;
        String mm = df.format(month);
        int day = time.get(Calendar.DAY_OF_MONTH);
        String dd = df.format(day);
        floodNo = year + mm + dd;
        return floodNo;
    }

    /**
     * 将字符串的长度扩展到length
     *
     * @return 扩展后的长度
     */
    public static String getString(String str, int length) {
        StringBuilder result = new StringBuilder();
        if (str == null) {
            for (int i = 0; i < length; i++) {
                result.append(" ");
            }
        } else {
            result = new StringBuilder(str);
            for (int i = str.length(); i < length; i++) {
                result.append(" ");
            }
        }
        return result.toString();
    }

    /**
     * 整8:00时间
     *
     * @return 某一天整8:00时间,小于等于8：00的取前一天8：00
     */
    public static Date getStandardTime(Date dt) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);
        if (cal.get(Calendar.HOUR_OF_DAY) < 8) {
            cal.add(Calendar.DATE, -1);
        }
        cal.set(Calendar.HOUR_OF_DAY, 8);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 整8:00时间
     *
     * @return 某一天整8:00时间,大于8：00的取后一天8：00
     */
    public static Date getEndEightTime(Date dt) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);
        if (cal.get(Calendar.HOUR_OF_DAY) > 8) {
            cal.add(Calendar.DATE, 1);
        }
        cal.set(Calendar.HOUR_OF_DAY, 8);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 整8:00时间
     *
     * @return 某一天整8:00时间
     */
    public static Date getEightTime(Date dt) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);
        cal.set(Calendar.HOUR_OF_DAY, 8);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    public static Date getDT(Date dt, int month, int day, int hour) {// 设置6月1号8时的时间
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);
        cal.set(Calendar.MONTH, month);
        cal.set(Calendar.DAY_OF_MONTH, day);
        cal.set(Calendar.HOUR_OF_DAY, hour);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    public static int daysAfter(Date dt_beg, Date dt_end) {// 两个时间相差的天数
        int days = -1;
        if ((dt_end.getTime() - dt_beg.getTime()) >= 0) {
            days = new Long((dt_end.getTime() - dt_beg.getTime()) / (24 * 3600 * 1000l)).intValue();
        }
        return days;
    }

    public static ArrayList sort(ArrayList list) {
        ArrayList result = new ArrayList();
        ArrayList listBak = (ArrayList) list.clone();
        return result;
    }

    public static Object copyOneObject(Object object) {// 序列化一个对象后进行复制
        Object copyObject = null;
        try {
            ByteArrayOutputStream buf1 = new ByteArrayOutputStream();
            ObjectOutputStream out1 = new ObjectOutputStream(buf1);
            out1.writeObject(object);
            ObjectInputStream in1 = new ObjectInputStream(new ByteArrayInputStream(buf1.toByteArray()));
            copyObject = in1.readObject();
        } catch (Exception e) {
        }
        return copyObject;
    }

    public static String[] convertDateToString(SimpleDateFormat formatter, Date[] dt) {
        if (dt == null) {
            return null;
        }
        int num = dt.length;
        String[] dtString = new String[num];
        for (int i = 0; i < num; i++) {
            dtString[i] = formatter.format(dt[i]);
        }
        return dtString;
    }

    public static Date[] convertStringToDate(SimpleDateFormat formatter, String[] dtString) throws Exception {
        if (dtString == null) {
            return null;
        }
        int num = dtString.length;
        Date[] dt = new Date[num];
        for (int i = 0; i < num; i++) {
            dt[i] = formatter.parse(dtString[i]);
        }
        return dt;
    }

    public static Date convertStringToDate(SimpleDateFormat formatter, String dtString) {
        if (dtString == null) {
            return null;
        }
        Date dt = null;
        try {
            dt = formatter.parse(dtString);
        } catch (Exception e) {
        }
        return dt;
    }

    public static boolean isExist(int x, int y[]) {
        if (y == null)
            return false;
        for (int j : y) {
            if (x == j) {
                return true;
            }
        }
        return false;
    }

    /*
     * public static float getTotalV(float[] q,int timeStep) {//获取洪量 if(q==null)
     * return 0; float total = 0; for(int i=0;i<q.length-1;i++) { float temp=new
     * Float(0.5*(q[i]+q[i+1])*timeStep*3600).floatValue(); total+=temp; }
     * return (float)(total/Math.pow(10,8)); }
     */

    public static float[] getProduct(float[] p, float multiplier) {// 一个数组的每个数都乘以相同的数
        for (int i = 0; i < p.length; i++) {
            p[i] = p[i] * multiplier;
        }
        return p;
    }

    public static float getSum(float[] p, int n) {// 获取洪量
        if (p == null) {
            return 0;
        }
        if (n == 0) {
            return 0;
        }
        float all = 0;
        for (int i = 0; i < n; i++) {
            all = all + p[i];
        }
        return all;
    }

    public static float[] getExtendArrary(float[] p, Date beg_DT, Date end_DT, Date dt0, Date dt1, int time_step,
                                          String step_unit, float insert) {// 扩充数组,insert为加进去的数
        if (p == null)
            return null;
        int i_floods = getPeriods(beg_DT, end_DT, time_step, step_unit);
        float[] temp = new float[i_floods];
        int num_beg = getPeriods(beg_DT, dt0, time_step, step_unit) - 1;
        if (num_beg < 0)
            num_beg = 0;

        if (i_floods < p.length) {
            for (int i = 0; i < num_beg; i++) {
                temp[i] = insert;
            }
            for (int i = num_beg; i < i_floods; i++) {
                temp[i] = p[i - num_beg];
            }
        } else {
            for (int i = 0; i < num_beg; i++) {
                temp[i] = insert;
            }
            for (int i = num_beg; i < num_beg + p.length; i++) {
                temp[i] = p[i - num_beg];
            }
            for (int i = num_beg + p.length; i < i_floods; i++) {
                temp[i] = insert;
            }
        }
        return temp;
    }

    public static Date[] getDateArrary(Date firstDate, int timeStep, int length) {// 获取以一时间开始后面的时间
        Date[] dateArray = new Date[length];
        for (int i = 0; i < length; i++) {
            dateArray[i] = datePlusHour(firstDate, i * timeStep);
        }
        return dateArray;
    }

    public static Date getTime(Date[] date, float[] x, float xmax, int n) {
        Date dt = new Date();
        for (int i = 0; i < n; i++) {
            if (Math.abs(x[i] - xmax) < 0.001) {
                dt = date[i];
            }
        }
        return dt;
    }

    public static Date getOverTime(Date[] date, float[] x, float limitx, int n) {
        Date dt = null;
        for (int i = 0; i < n; i++) {
            if (x[i] >= limitx) {
                dt = date[i];
                break;
            }
        }
        return dt;
    }

    public static Date getBackTime(Date[] date, float[] x, Date overLimitxDate, float limitx, int n) {
        Date dt = null;
        for (int i = 0; i < n; i++) {
            if (date[i].after(overLimitxDate)) {
                if (x[i] <= limitx) {
                    dt = date[i];
                    break;
                }
            }
        }
        return dt;
    }

    public static float getTotalV(float[] q, Date[] dt, int num, int vUnit) {// 得到洪量，单位和库容单位相同
        if (q == null)
            return 0;
        if (num <= 1) {
            return 0;
        }
        float total = 0;
        for (int i = 0; i < num - 1; i++) {
            long timeStep = (long) ((dt[i + 1].getTime() - dt[i].getTime()) / 1000L);
            float temp = (float) (q[i + 1] * timeStep);
            total += temp;
        }
        if (vUnit == 1) {
            total = total / 10000L;
        }
        if (vUnit == 2) {
            total = total / 1000000L;
        }
        if (vUnit == 3) {
            total = total / 100000000L;
        }
        return (float) (total);
    }

    public static float getTotalV(float[] q, Date[] dt, int num) {// 得到洪量，显示的时候用，单位都是百万方
        if (q == null)
            return 0;
        if (num <= 1) {
            return 0;
        }
        float total = 0;
        for (int i = 0; i < num - 1; i++) {
            long timeStep = (long) ((dt[i + 1].getTime() - dt[i].getTime()) / 1000L);
            float temp = (float) (q[i + 1] * timeStep);
            total += temp;
        }
        total = total / 1000000L;
        return (float) (total);
    }

    public static float getArea(float[] q, Date[] dt, int num) {// 得到洪量，显示的时候用，单位都是百万方
        if (q == null)
            return 0;
        if (num <= 1) {
            return 0;
        }
        float total = 0;
        for (int i = 0; i < num - 1; i++) {
            long timeStep = (long) ((dt[i + 1].getTime() - dt[i].getTime()) / 1000L);
            float temp = (float) ((q[i + 1] + q[i + 1]) * 0.5f * timeStep);
            total += temp;
        }
        total = total / 1000000L;
        return (float) (total);
    }

    public static Date getFormerDate(Date dt, int hour) {
        Date formerDate;
        Calendar time = Calendar.getInstance();
        time.setTime(dt);
        time.add(Calendar.HOUR, hour);
        formerDate = time.getTime();
        return formerDate;
    }

    public static float[] getSameData(float[] data) {
        float[] sameData = new float[data.length];
        System.arraycopy(data, 0, sameData, 0, data.length);
        return sameData;
    }

    /**
     * 获取最大值所在的位置的下标
     */
    public static int getMaxNo(float[] q) {
        float max = -1;
        int no = 0;
        for (int i = 0; i < q.length; i++) {
            if (q[i] > max) {
                max = q[i];
                no = i;
            }
        }
        return no;
    }

    /**
     * 去掉数据组中重复的元素
     */
    public static String[] getDistinct(String[] array) {
        List list = new ArrayList();
        for (String s : array) {
            if (!list.contains(s)) {
                list.add(s);
            }
        }
        return (String[]) list.toArray(new String[1]);
    }

    /**
     * 去掉数组中重复的元素
     */
    public static int[] getDistinct(int[] array) {
        List list = new ArrayList<>();
        for (int j : array) {
            if (!list.contains(j)) {
                list.add(j);
            }
        }
        int[] newInt = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            newInt[i] = Integer.parseInt(list.get(i).toString());
        }
        return newInt;
    }

    /**
     * 找出数组中的最大值与最小值, 返回值第一个为最大值, 第二个为最小值
     */
    public static float[] findMaxMin(float[] array) {
        float[] maxmin = new float[2];
        maxmin[0] = array[0];
        maxmin[1] = array[0];
        for (int i = 1; i < array.length; i++) {
            if (array[i] > maxmin[0])
                maxmin[0] = array[i];
            if (array[i] < maxmin[1])
                maxmin[1] = array[i];
        }
        return maxmin;
    }

    public static String[] convertIntArrToStringArr(int[] intArr) {
        String[] strArr = new String[intArr.length];
        for (int i = 0; i < intArr.length; i++) {
            strArr[i] = intArr[i] + "";
        }
        return strArr;
    }

    public static Float convertToFloat(Double doubleValue) {
        return doubleValue == null ? null : doubleValue.floatValue();
    }

    /**
     * 阶梯插值
     */
    public static float[] insertStep(float[] input, int timeStepInput, int timeStepOutput) {
        if (input == null)
            return null;
        if (timeStepOutput % timeStepInput != 0)
            return null;
        int times = timeStepOutput / timeStepInput;
        int length = times * input.length;
        float[] output = new float[length];
        for (int i = 0; i < length; i++) {
            output[i] = input[i / times];
        }

        return output;
    }

    /**
     * 线性插值
     */
    public static float[] insertLine(float[] input, int timeStepInput, int timeStepOutput) {
        if (input == null)
            return null;
        if (timeStepOutput % timeStepInput != 0)
            return null;
        int times = timeStepOutput / timeStepInput;
        int length = times * input.length;
        float[] output = new float[length];
        for (int i = 0; i < length; i++) {
            int j = i / times;
            if (j == 0) {
                output[i] = input[j];
            } else {
                output[i] = input[j - 1] + (i % times) * (input[j] - input[j - 1]) / times;
            }
        }

        return output;
    }

    public static int getTimeStepHours(Date dt_beg, Date dt_end) {
        int timeStep = -1;
        if ((dt_end.getTime() - dt_beg.getTime()) >= 0) {
            timeStep = new Long((dt_end.getTime() - dt_beg.getTime()) / (3600 * 1000L)).intValue();
        }
        return timeStep;
    }

    public static int getTimeStepMinutes(Date dt_beg, Date dt_end) {
        int timeStep = -1;
        if ((dt_end.getTime() - dt_beg.getTime()) >= 0) {
            timeStep = new Long((dt_end.getTime() - dt_beg.getTime()) / (60 * 1000L)).intValue();
        }
        return timeStep;
    }

    /**
     * 单位转化
     */
    public static double multiKFromFlowToVolumn(double clen, String unt) {
        if (unt == null)
            unt = "H";
        switch (unt) {
            case "D":
                return clen * 24 * 3600 / 1000000.0;
            case "H":
                return clen * 3600 / 1000000.0;
            case "M":
                return clen * 60  / 1000000.0;
            default:
                return clen * 3600 / 1000000.0;
        }
    }
}
